﻿using Newtonsoft.Json.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using SuperX.Common.Respository;

namespace SuperX.Common.Helper
{
    // 
    public static class JsonHelper
    {
        public static string JsonSerialize(object obj)
        {
            JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Ignore,
            };
            IsoDateTimeConverter isoDateTimeConverter = new IsoDateTimeConverter();
            isoDateTimeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";
            jsonSerializerSettings.Converters.Add(isoDateTimeConverter);
            jsonSerializerSettings.Converters.Add(new IPAddressConverter());
            jsonSerializerSettings.Converters.Add(new IPEndPointConverter());
            return JsonConvert.SerializeObject(obj, Formatting.Indented, jsonSerializerSettings);
        }

        // 
        public static string JsonSerializeToFile(object obj, string path, Encoding encoding)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }
            JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Ignore,
            };
            IsoDateTimeConverter isoDateTimeConverter = new IsoDateTimeConverter();
            isoDateTimeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";
            jsonSerializerSettings.Converters.Add(isoDateTimeConverter);
            jsonSerializerSettings.Converters.Add(new IPAddressConverter());
            jsonSerializerSettings.Converters.Add(new IPEndPointConverter());
            string text = JsonConvert.SerializeObject(obj, Formatting.Indented, jsonSerializerSettings);
            File.WriteAllText(path, text, encoding);
            return text;
        }

        // 
        public static string JsonSerializeToFile(object obj, string path, Encoding encoding, string key)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }
            JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Ignore
            };
            IsoDateTimeConverter isoDateTimeConverter = new IsoDateTimeConverter();
            isoDateTimeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";
            jsonSerializerSettings.Converters.Add(isoDateTimeConverter);
            jsonSerializerSettings.Converters.Add(new IPAddressConverter());
            jsonSerializerSettings.Converters.Add(new IPEndPointConverter());
            string text = JsonConvert.SerializeObject(obj, 0, jsonSerializerSettings);
            text = SafetyUtil.DesEncrypt(text, (string.IsNullOrWhiteSpace(key) || key.Length != 8) ? defaultKey : key, defaultCiv);
            File.WriteAllText(path, text, encoding);
            return text;
        }

        // 
        public static object JsonDeserialize(string content)
        {
            return JsonConvert.DeserializeObject(content);
        }

        // 
        public static object JsonDeserialize(string content, Type type)
        {
            return JsonConvert.DeserializeObject(content, type);
        }

        // 
        public static T JsonDeserialize<T>(string content)
        {
            return JsonConvert.DeserializeObject<T>(content);
        }

        // 
        public static object JsonDeserializeFromFile(string path, Type type, Encoding encoding)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }
            if (encoding == null)
            {
                throw new ArgumentNullException("encoding");
            }
            return JsonConvert.DeserializeObject(File.ReadAllText(path, encoding), type);
        }

        // 
        public static object JsonDeserializeFromFile(string path, Type type, Encoding encoding, string key)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }
            if (encoding == null)
            {
                throw new ArgumentNullException("encoding");
            }
            return JsonConvert.DeserializeObject(SafetyUtil.DesDecrypt(File.ReadAllText(path, encoding), (string.IsNullOrWhiteSpace(key) || key.Length != 8) ? defaultKey : key,defaultCiv), type);
        }

        //
        public static string TransferObjectJsonSerialize(object obj, bool defaultValueIgnore = true)
        {
            JsonSerializerSettings transferObjectSettting = JsonHelper.GetTransferObjectSettting(defaultValueIgnore);
            return JsonHelper.TransferObjectJsonSerialize(obj, transferObjectSettting);
        }

        // 
        public static string TransferObjectJsonSerialize(object obj, JsonSerializerSettings setting)
        {
            if (obj == null)
            {
                return string.Empty;
            }
            return JsonConvert.SerializeObject(obj, 0, (setting == null) ? JsonHelper.GetTransferObjectSettting(true) : setting);
        }

        // 
        public static T TransferObjectJsonDeserialize<T>(string content)
        {
            return JsonHelper.TransferObjectJsonDeserialize<T>(content, JsonHelper.GetTransferObjectSettting(true));
        }

        // 
        public static T TransferObjectJsonDeserialize<T>(string content, JsonSerializerSettings setting)
        {
            if (string.IsNullOrEmpty(content))
            {
                return default(T);
            }
            return JsonConvert.DeserializeObject<T>(content, (setting == null) ? JsonHelper.GetTransferObjectSettting(true) : setting);
        }

        // 
        public static object TransferObjectJsonDeserialize(string content, Type type)
        {
            return JsonHelper.TransferObjectJsonDeserialize(content, type, JsonHelper.GetTransferObjectSettting(true));
        }

        // 
        public static object TransferObjectJsonDeserialize(string content, Type type, JsonSerializerSettings setting)
        {
            if (string.IsNullOrEmpty(content))
            {
                return null;
            }
            return JsonConvert.DeserializeObject(content, type, (setting == null) ? JsonHelper.GetTransferObjectSettting(true) : setting);
        }

        // 
        private static JsonSerializerSettings GetTransferObjectSettting(bool defaultValueIgnore = true)
        {
            if (JsonHelper._transferObjectSettings == null)
            {
                JsonHelper._transferObjectSettings = new JsonSerializerSettings();
                JsonHelper._transferObjectSettings.ContractResolver = new LimitPropsContractResolver();
                IsoDateTimeConverter item = new IsoDateTimeConverter
                {
                    DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff"
                };
                JsonHelper._transferObjectSettings.Converters.Add(item);
                JsonHelper._transferObjectSettings.Converters.Add(new IPAddressConverter());
                JsonHelper._transferObjectSettings.Converters.Add(new IPEndPointConverter());
            }
            JsonHelper._transferObjectSettings.DefaultValueHandling = (defaultValueIgnore ? DefaultValueHandling.Ignore : DefaultValueHandling.Include);
            return JsonHelper._transferObjectSettings;
        }

        private static JsonSerializerSettings _transferObjectSettings;
        private const string defaultKey = "fGhjsK78";
        private const string defaultCiv = "ss8edKe3rTsfhH43c+ddwKUs";
    }
}
